﻿unit ServerController;

interface

uses
  System.SysUtils, System.Classes, System.Generics.Collections,
  Sparkle.HttpSys.Server, Sparkle.HttpServer.Module,  Sparkle.HttpServer.Dispatcher,
  ServerModuleManager, EnhancedServerModule, RateLimitMiddleware,
  LoginModule,UserModule,ExampleModule;

type
  TServerController = class
  private
    FServer: TCustomHttpSysServer;
    FModuleManager: TServerModuleManager;
    FRateLimitMiddleware: TRateLimitMiddleware;
    FPort: Integer;
    FIsRunning: Boolean;

    procedure ConfigureServer;
    procedure RegisterDefaultModules;
  public
    constructor Create(Port: Integer = 9990);
    destructor Destroy; override;

    procedure Start;
    procedure Stop;
    procedure Restart;

    procedure RegisterModule(const Name: string; Module: TEnhancedServerModule);
    procedure UnregisterModule(const Name: string);

    property IsRunning: Boolean read FIsRunning;
    property Port: Integer read FPort write FPort;
  end;

implementation

{ TServerController }

constructor TServerController.Create(Port: Integer);
begin
  inherited Create;
  FPort := Port;
  FModuleManager := TServerModuleManager.Instance;
  FServer := TCustomHttpSysServer.Create;
  FRateLimitMiddleware := TRateLimitMiddleware.Create(1000, 1);

  // 设置服务器日志
  FServer.LogEngine := FModuleManager.LogEngine;

  ConfigureServer;
  RegisterDefaultModules;

  FModuleManager.Logger.Info(Format('ServerController created on port %d', [Port]));
end;

destructor TServerController.Destroy;
begin
  try
    try
      if Assigned(FServer) then
      begin
        if FServer.IsRunning then
          FServer.Stop;
      end;
    except
      // 忽略异常
    end;
  finally
    // 无论如何都要调用父类
    inherited;
  end;
end;

procedure TServerController.ConfigureServer;
begin
  // 关键设置：允许监听所有主机
  FServer.KeepHostInUrlPrefixes := False;
  FModuleManager.Logger.Debug('Server configured with KeepHostInUrlPrefixes = False');
end;

procedure TServerController.RegisterDefaultModules;
var
  LoginModule: TLoginModule;
  UserModule: TUserModule;
  ExampleModule : TExampleModule;
begin
  // 使用完整的URL注册模块
  UserModule := TUserModule.Create(Format('http://localhost:%d/api/user', [FPort]));
  RegisterModule('User', UserModule);

  // 添加调试信息
  FModuleManager.Logger.Info(Format('UserModule registered with BaseUri: %s', [UserModule.BaseUri.OriginalUri]));

  LoginModule := TLoginModule.Create(Format('http://localhost:%d/auth', [FPort]));
  RegisterModule('Auth', LoginModule);

  // 添加调试信息
  FModuleManager.Logger.Info(Format('LoginModule registered with BaseUri: %s', [LoginModule.BaseUri.OriginalUri]));

  // 注册示例模块
  ExampleModule := TExampleModule.Create(Format('http://localhost:%d/api/examples', [FPort]));
  RegisterModule('Examples', ExampleModule);
  FModuleManager.Logger.Info(Format('ExampleModule registered with BaseUri: %s', [ExampleModule.BaseUri.OriginalUri]));



  FModuleManager.Logger.Debug('Default modules registration completed');
end;

procedure TServerController.RegisterModule(const Name: string;
  Module: TEnhancedServerModule);
begin
  // 添加限流中间件
  Module.AddMiddleware(FRateLimitMiddleware);

  FModuleManager.RegisterModule(Name, Module, Module as IModuleLifecycle);
  FServer.AddModule(Module);

  FModuleManager.Logger.Info(Format('Module %s registered with server', [Name]));
end;

procedure TServerController.UnregisterModule(const Name: string);
begin
  FModuleManager.UnregisterModule(Name);
  FModuleManager.Logger.Info(Format('Module %s unregistered', [Name]));
end;

procedure TServerController.Start;
var
  ModuleInfo: THttpServerModuleInfo;
begin
  if FIsRunning then
  begin
    FModuleManager.Logger.Warning('Server is already running');
    Exit;
  end;

  try
    FModuleManager.Logger.Info(Format('Starting server on port %d', [FPort]));

    // 验证 URL 前缀
    FModuleManager.Logger.Debug('Registered URL prefixes:');
    for ModuleInfo in FServer.Dispatcher.ModulesInfo do
    begin
      FModuleManager.Logger.Debug(Format('  - %s', [ModuleInfo.BaseUri.OriginalUri]));
    end;

    FServer.Start;
    FModuleManager.StartAll;
    FIsRunning := True;

    FModuleManager.Logger.Info(Format('Server started successfully on port %d', [FPort]));
  except
    on E: Exception do
    begin
      FModuleManager.Logger.Error('Failed to start server: ' + E.Message);
      raise;
    end;
  end;
end;

procedure TServerController.Stop;
begin
  if not FIsRunning then
  begin
    FModuleManager.Logger.Warning('Server is not running');
    Exit;
  end;

  try
    FModuleManager.Logger.Info('Stopping server...');

    // 先停止模块管理器
    FModuleManager.StopAll;

    // 给一些时间让现有请求完成
    Sleep(500);

    // 然后停止服务器
    FServer.Stop;
    FIsRunning := False;

    FModuleManager.Logger.Info('Server stopped successfully');
  except
    on E: Exception do
    begin
      FModuleManager.Logger.Error('Failed to stop server: ' + E.Message);
      // 在析构函数中不要重新抛出异常
    end;
  end;
end;


procedure TServerController.Restart;
begin
  FModuleManager.Logger.Info('Restarting server...');
  Stop;
  Start;
  FModuleManager.Logger.Info('Server restarted successfully');
end;

end.
